import random
import linecache
import numpy
import os

class UserModel(object):
    SHARPNESS = -3
    PATH_PROXIMITY = os.path.dirname(__file__) + '/ProximityMatrix/'
    NOISE = 0.1


    def __init__(self, number_of_images, setsize, filename):
        self.filename = filename
        self.number_of_images = number_of_images
        self.setsize = setsize
        self.target = random.randint(0, self.number_of_images-1)     
        #self.target = 0
    def getTarget(self):
        return self.target
        
    def Select(self, images):
 #       print images
        
        relevance_scores = dict()
        average_distance = 0 
        minimum_distance = 0
       
    
        distances_line = self.GetVector(self.target)
        distances_to_target = []
        for image in images:
             distances_to_target.append(distances_line[image])
        # print 'distance to target ', distances_to_target
        distances_to_target = numpy.array((distances_to_target))
        average_distance = numpy.mean(distances_to_target)
        minimum_distance = numpy.min(distances_to_target)
  #     print 'Average distance to target = ', average_distance
        similarities_to_target = distances_to_target**UserModel.SHARPNESS
        probabilities  = (1-UserModel.NOISE)*similarities_to_target/sum(similarities_to_target)+UserModel.NOISE/self.setsize
        chosen_index, relevance = self.Sample(probabilities)
        
        i = 0
        for image in images:
            relevance_scores[image] = relevance[i]
            i += 1
        
        chosen_image = images[chosen_index]
        chosen_distance = distances_to_target[chosen_index]
       
        if self.target in images:
            chosen_image = self.target
            chosen_distance = 0
                    
        return chosen_image, relevance_scores, average_distance, chosen_distance, minimum_distance
                
    def Sample (self, probabilities):
        
#        print 'Probabilities = ', probabilities
              
        relevance_scores = []
          
        r = random.random()
        cumulative_sum = probabilities[0]
        index = 0
        while cumulative_sum < r:
            relevance_scores.append(0)
            index += 1
            cumulative_sum = cumulative_sum + probabilities[index]
        chosen_image = index
        relevance_scores.append(1)
        while len(relevance_scores)<len(probabilities):
            relevance_scores.append(0)
        
        return chosen_image, relevance_scores

    def GetVector(self, number):
        # Get vector from line #number from file input
        # number starts from 1
        distance_file = UserModel.PATH_PROXIMITY + self.filename + str(self.number_of_images) + '_Euclidean.dist' 
        line = linecache.getline(distance_file, number+1)
        return map(float, line.split())
        
        